﻿#ifndef HNRJITCONTAINER_H
#define HNRJITCONTAINER_H

#include "HnrjitWigdet.h"

class CHnrjitControl;
class CHnrjitDialog;

class DIRECTUI_API CHnrjitContainer : public CHnrjitWigdet
{
public:
	/// <summary>构造函数</summary>
	/// <param name="pParentDialog">父对话框</param>
	explicit CHnrjitContainer(CHnrjitDialog* pParentDialog);

	/// <summary>析构函数</summary>
	virtual ~CHnrjitContainer();

	/// <summary>获取当前类标识</summary>
	virtual DWORD GetClsid() const { return CLSID_HNRJITCONTAINER; }

	/// <summary>设置属性值</summary>
	/// <param name="pxElement">XML元素</param>
	virtual void SetAttribute(const TiXmlElement* pxElement, HZIP hZipRes = NULL);

public:
	/// <summary>添加控件</summary>
	/// <param name="pControl">欲添加的控件</param>
	/// <returns>是否添加成功</returns>
	BOOL AddControl(CHnrjitControl* pControl);

	/// <summary>添加控件</summary>
	/// <param name="nIndex">欲插入的索引</param>
	/// <param name="pControl">欲添加的控件</param>
	/// <returns>是否添加成功</returns>
	/// <remarks>当"nIndex"大于控件总数时则追加到最后</remarks>
	BOOL AddControl(UINT nIndex, CHnrjitControl* pControl);

	/// <summary>移除控件</summary>
	/// <param name="pControl">欲删除的控件</param>
	/// <returns>是否移除成功</returns>
	BOOL RemoveControl(CHnrjitControl* pControl);

	/// <summary>移除控件</summary>
	/// <param name="nIndex">欲删除的索引</param>
	/// <returns>是否移除成功</returns>
	BOOL RemoveControl(UINT nIndex);

	/// <summary>移除所有控件</summary>
	void RemoveAllControl();

	/// <summary>获取控件</summary>
	/// <param name="nIndex">指定索引</param>
	/// <returns>指定控件</returns>
	CHnrjitControl* GetControl(UINT nIndex) const;

	/// <summary>获取控件索引</summary>
	/// <param name="pControl">指定控件</param>
	/// <returns>指定索引</returns>
	LONG GetControlIndex(CHnrjitControl* pControl) const;

	/// <summary>获取控件总数</summary>
	/// <returns>控件总数</returns>
	UINT GetControlCount() const;

	/// <summary>获取活动控件</summary>
	/// <returns>活动控件</returns>
	CHnrjitControl* GetActivate() const;

	/// <summary>设置活动控件</summary>
	/// <param name="pControl">欲设置的控件（可为NULL）</param>
	/// <returns>是否设置成功</returns>
	/// <remarks>控件"pControl"为NULL时没有活动控件</remarks>
	BOOL SetActivate(CHnrjitControl* pControl);

	/// <summary>设置活动控件</summary>
	/// <param name="nIndex">欲设置的索引</param>
	/// <returns>是否设置成功</returns>
	/// <remarks>"nIndex"必须小于控件总数</remarks>
	BOOL SetActivate(UINT nIndex);

	/// <summary>容器背景颜色</summary>
	COLORREF GetBackColor() const;
	void SetBackColor(COLORREF crBackColor);

	/// <summary>容器边框颜色</summary>
	COLORREF GetBorderColor() const;
	void SetBorderColor(COLORREF crBorderColor);

	/// <summary>设置背景图片</summary>
	/// <param name="imgPicture">背景图片</param>
	/// <param name="bResize">是否根据背景图片调整容器大小</param>
	void SetBackImage(CComPtr<IImage> imgPicture, BOOL bResize = FALSE);

private:
	/// <summary>设置“单选框”或“复选框”选中状态</summary>
	/// <param name="pControl">“单选框”或“复选框”</param>
	/// <param name="isChecked">是否选中状态</param>
	void SetChecked(CHnrjitControl* pControl, BOOL isChecked);

public:
	/// <summary>控件单击事件</summary>
	/// <param name="pControl">被单击的控件</param>
	/// <remarks>建议重载</remarks>
	virtual void OnClicked(CHnrjitControl* pControl);

	/// <summary>键盘按下事件</summary>
	/// <param name="nChar">虚拟键码</param>
	/// <param name="nRepCnt">重复次数</param>
	/// <param name="nFlags">扫描代码</param>
	virtual void OnKeyPress(UINT nChar, UINT nRepCnt, UINT nFlags);

	/// <summary>键盘释放事件</summary>
	/// <param name="nChar">虚拟键码</param>
	/// <param name="nRepCnt">重复次数</param>
	/// <param name="nFlags">扫描代码</param>
	virtual void OnKeyRelease(UINT nChar, UINT nRepCnt, UINT nFlags);

	/// <summary>鼠标按下事件</summary>
	/// <param name="nFlags">按下的键</param>
	/// <param name="point">鼠标位置</param>
	virtual void OnMousePress(UINT nFlags, CPoint point);

	/// <summary>鼠标释放事件</summary>
	/// <param name="nFlags">按下的键</param>
	/// <param name="point">鼠标位置</param>
	virtual void OnMouseRelease(UINT nFlags, CPoint point);

	/// <summary>鼠标移动事件</summary>
	/// <param name="nFlags">按下的键</param>
	/// <param name="point">鼠标位置</param>
	virtual void OnMouseMove(UINT nFlags, CPoint point);

public:
	/// <summary>请求重绘容器</summary>
	/// <param name="rcRect">重绘区域</param>
	virtual void Invalidate(const CRect& rcRect);

	/// <summary>渲染容器</summary>
	/// <param name="rcClipBox">裁剪区域</param>
	/// <param name="pDC">设备上下文</param>
	virtual void DrawClipBox(HDC hdc, const CRect& rcClipBox);

protected:
	HBITMAP m_hbmpBackImage; // 背景位图（由于背景绘制次数比较多，转换成位图能一定程度上减少对CPU的消耗）

	COLORREF m_crBackColor; // 背景颜色

	COLORREF m_3dBorderColor; // 边缘颜色

	CAtlArray<CHnrjitControl* > m_arrControls; // 控件数组

	CHnrjitControl* m_pFocusControl; // 聚集控件

	CHnrjitDialog* m_pParentDialog; // 父对话框
};

#endif // HNRJITCONTAINER_H